home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / PROG_TOO / C027B.ZIP / LIBFP / PRINTF.C < prev    next >
Text File  |  1990-03-30  |  3KB  |  172 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3.  
  4. _printf(op, put, fmt, args)
  5.     char *op;
  6.     unsigned int (*put)();
  7.     register unsigned char *fmt;
  8.     register unsigned int *args;
  9.     {
  10.     register int i, cnt = 0, ljustf, lval;
  11.     int preci, dpoint, width;
  12.     char pad, sign, radix;
  13.     register char *ptmp;
  14.     char tmp[64], *ltoa(), *ultoa();
  15. #if FLOATS
  16.     double fx;
  17. #endif
  18.  
  19.     while(*fmt)
  20.         {
  21.         if(*fmt == '%')
  22.             {
  23.             ljustf = FALSE;    /* left justify flag */
  24.             sign = '\0';    /* sign char & status */
  25.             pad = ' ';    /* justification padding char */
  26.             width = -1;    /* min field width */
  27.             dpoint = FALSE;    /* found decimal point */
  28.             preci = -1;    /* max data width */
  29.             radix = 10;    /* number base */
  30.             ptmp = tmp;    /* pointer to area to print */
  31.             lval = FALSE;    /* long value flaged */
  32. fmtnxt:
  33.             i = 0;
  34.             while (isdigit(*++fmt))
  35.                 {
  36.                 i = (i * 10) + (*fmt - '0');
  37.                 if (dpoint)
  38.                     preci = i;
  39.                 else if (!i && (pad == ' '))
  40.                     {
  41.                     pad = '0';
  42.                     goto fmtnxt;
  43.                     }
  44.                 else
  45.                     width = i;
  46.                 }
  47.  
  48.             switch(*fmt)
  49.                 {
  50.                 case '\0':    /* early EOS */
  51.                     --fmt;
  52.                     goto charout;
  53.  
  54.                 case '-':    /* left justification */
  55.                     ljustf = TRUE;
  56.                     goto fmtnxt;
  57.  
  58.                 case ' ':
  59.                 case '+':    /* leading sign flag */
  60.                     sign = *fmt;
  61.                     goto fmtnxt;
  62.  
  63.                 case '*':    /* parameter width value */
  64.                     i = *args++;
  65.                     if (dpoint)
  66.                         preci = i;
  67.                     else
  68.                         width = i;
  69.                     goto fmtnxt;
  70.  
  71.                 case '.':    /* secondary width field */
  72.                     dpoint = TRUE;
  73.                     goto fmtnxt;
  74.  
  75.                 case 'l':    /* long data */
  76.                     lval = TRUE;
  77.                     goto fmtnxt;
  78.  
  79.                 case 'd':    /* Signed decimal */
  80.                 case 'i':
  81.                     ltoa((long)((lval)
  82.                         ?(*((long *) args))
  83.                         :(*((int  *) args))),
  84.                           ptmp, 10);
  85.                     if(lval)
  86.                         args = ((unsigned int *)
  87.                             (((long *) args) + 1));
  88.                     else
  89.                         args = ((unsigned int *)
  90.                             (((int *) args) + 1));
  91.                     goto printit;
  92.  
  93.                 case 'b':    /* Unsigned binary */
  94.                     radix = 2;
  95.                     goto usproc;
  96.  
  97.                 case 'o':    /* Unsigned octal */
  98.                     radix = 8;
  99.                     goto usproc;
  100.  
  101.                 case 'p':    /* Pointer */
  102.                     lval = TRUE;
  103.                     pad = '0';
  104.                     width = 6;
  105.                     preci = 8;
  106.                     /* fall thru */
  107.  
  108.                 case 'x':    /* Unsigned hexadecimal */
  109.                 case 'X':
  110.                     radix = 16;
  111.                     /* fall thru */
  112.  
  113.                 case 'u':    /* Unsigned decimal */
  114. usproc:
  115.                     ultoa((unsigned long)((lval)
  116.                         ?(*((unsigned long *) args))
  117.                         : *args++ ),
  118.                           ptmp, radix);
  119.                     if(lval)
  120.                         args = ((unsigned int *)
  121.                         (((unsigned long *) args) + 1));
  122.                     if (*fmt == 'x')
  123.                         strlwr(ptmp, ptmp);
  124.                     goto printit;
  125.  
  126. #if FLOATS
  127.                 case 'e':    /* float */
  128.                 case 'f':
  129.                 case 'g':
  130.                 case 'E':
  131.                 case 'G':
  132.                     fx = *((double *) args);
  133.                     args=(unsigned int *)
  134.                          (((double *) args)+1);
  135.  
  136.                     fp_print(fx, *fmt, preci, ptmp);
  137.                     preci = -1;
  138.                     goto printit;
  139. #endif
  140.  
  141.                 case 'c':    /* Character */
  142.                     ptmp[0] = *args++;
  143.                     ptmp[1] = '\0';
  144.                     goto nopad;
  145.  
  146.                 case 's':    /* String */
  147.                     ptmp = *((char **) args);
  148.                     args = ((unsigned int *)
  149.                         (((char **) args) + 1));
  150. nopad:
  151.                     sign = '\0';
  152.                     pad  = ' ';
  153. printit:
  154.                     cnt += _prtfld(op, put, ptmp, ljustf,
  155.                                sign, pad, width, preci);
  156.                     break;
  157.  
  158.                 default:    /* unknown character */
  159.                     goto charout;
  160.                 }
  161.             }
  162.         else
  163.             {
  164. charout:
  165.             (*put)(*fmt, op);        /* normal char out */
  166.             ++cnt;
  167.             }
  168.         ++fmt;
  169.         }
  170.     return(cnt);
  171.     }
  172.